package com.mindata.blockchain.core.manager;

import com.mindata.blockchain.common.CountDoData;
import com.mindata.blockchain.common.DateUtils;
import com.mindata.blockchain.core.bean.SelectCountResult;
import com.mindata.blockchain.core.model.CountResult;
import com.mindata.blockchain.core.model.MessageEntity;
import com.mindata.blockchain.core.repository.MessageRepository;
import io.swagger.models.auth.In;
import org.hibernate.MappingException;
import org.springframework.orm.jpa.JpaSystemException;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author wuweifeng wrote on 2018/3/28.
 */
@Component
public class MessageManager {

    @PersistenceContext
    private EntityManager entityManager;

    @Resource
    private MessageRepository messageRepository;

    public List<MessageEntity> findAll() {
        return messageRepository.findAll();
    }



    public List<String> findAllContent() {
        return findAll().stream().map(MessageEntity::getContent).collect(Collectors.toList());
    }

    public MessageEntity findById(String id) {
        return messageRepository.findByMessageId(id);
    }

    public CountResult getCountDetailByParam(List<String> dates){
        //获取结果集
       /* String hql ="SELECT count(1) count1,ct day  ,'data' type  from (select strftime('%Y-%m-%d',datetime(substr(create_time,1,10), 'unixepoch', 'localtime')) as ct from message) a where a.ct BETWEEN  strftime('%Y-%m-%d','2020-08-24 14:38:01') and  strftime('%Y-%m-%d','2020-08-26 14:38:01')  GROUP BY a.ct";
        Query query = entityManager.createNativeQuery(hql);
        List list  = query.getResultList();
*/
        List<Object> list = null;
        try {
            list =  messageRepository.getResourcesCountByType(dates.get(0), dates.get(dates.size() - 1));
        }catch (MappingException e){
            if (e.getLocalizedMessage().indexOf("No")!=-1){
                list = new ArrayList<>();
            }
        }catch (JpaSystemException e){
            if (e.getLocalizedMessage().contains("No")){
                list = new ArrayList<>();
            }
        }

        System.out.println(list);

        List<SelectCountResult> selectCountResults = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            SelectCountResult selectCountResult = new SelectCountResult();
            Object[] obj = (Object[])list.get(i);
            selectCountResult.setCount1(Integer.parseInt(obj[0].toString()));
            selectCountResult.setDay(obj[1].toString());
            selectCountResult.setType(obj[2].toString().trim());
            selectCountResults.add(selectCountResult);
        }



//        List<SelectCountResult> resourcesCountByType = messageRepository.getResourcesCountByType(dates.get(0), dates.get(dates.size() - 1));

//        System.out.println(resourcesCountByType);
//        List<SelectCountResult> ss = JSONArray.parseArray(resourcesCountByType,SelectCountResult.class);

       // System.out.println("selectCountResult"+resourcesCountByType);
        //添加类型集合
        List<String> types = new ArrayList<String>();
        Collections.addAll(types,"data");
        //结果集的组装优化
        CountResult countResult = convertResultYH(selectCountResults, types, dates);
        //return  countResult;
        return countResult;
    }


    /**
     *@描述  结果集的组装优化
     *@参数  [selectCountResult, tyeps, dates]
     *@返回值  com.ztgeo.hlw.bespeak.entity.CountResult
     *@创建人  ws
     */
    private CountResult convertResultYH(List<SelectCountResult> selectCountResult, List<String> types, List<String> dates) {
        CountResult countResult = new CountResult();
        List<CountDoData> countDoDataList = new ArrayList<>();
        //1. 将结果集遍历
        String temptype = types.get(0);//type的临时变量
        String tempDate= dates.get(0);//日期临时变量
        CountDoData countDoData = new CountDoData();//初始化其中一个type名称+结果集
        List<Integer> dataArray = new ArrayList<>();//初始化一个数据集合
        //赋值结果集
        countDoData.setType(temptype);
        countDoData.setDataArray(dataArray);
        countDoDataList.add(countDoData);
        //初始化一个结果集
        for (int i = 0; i < selectCountResult.size(); i++) {  //遍历所有的结果集
            SelectCountResult selectCountResult1 = selectCountResult.get(i);

            String day = selectCountResult1.getDay();//日期
            Integer count = selectCountResult1.getCount1();//总条数
            String type = selectCountResult1.getType();//受理type

            //判断type名称和type变量是否相同
            if(!type.equals(temptype)){ //不相同
                //需要新new出一个对象
                countDoData = new CountDoData();
                //日期变量和 type变量 都需要改变
                temptype = type;
                tempDate =dates.get(0) ;//日期变量复位
                dataArray = new ArrayList<>();
                countDoData.setType(temptype);
                countDoData.setDataArray(dataArray);
                countDoDataList.add(countDoData);
            }
            //判断该条记录的日期是否和初始变量相同
            if(day.equals(tempDate)){//和日期变量相同
                //直接将该count 赋值给dataArray
                dataArray.add(count);
                //日期临时变量加1
                tempDate = DateUtils.getAddDate(tempDate,1);
            }else {//和日期变量不同 有差值天数的存在（日期不连续）
                //计算出该条日期变量和原来的日期变量的差距天数 并循环出该天数
                int day_disparity = DateUtils.differentDaysByMillisecond(day,tempDate);
                //循环补充条数0 中间差几天补充几个0
                for (int j = 0; j < day_disparity; j++) {
                    //赋值0
                    dataArray.add(0);
                }
                //天数补充完整后 重新执行统计函数的赋值和日期变量+1的操作
                dataArray.add(count);
                tempDate = DateUtils.getAddDate(tempDate,day_disparity+1);
            }
        }
        //循环DoDataList 看是否结果集长度和日期长度不同 如果不同 算出后端差位进行补零操作
        for (int i = 0; i < countDoDataList.size(); i++) {
            int dataArraySize = dates.size()-countDoDataList.get(i).getDataArray().size();
            if(dataArraySize>0){//需要补零
                for (int j = 0; j < dataArraySize; j++) {
                    countDoDataList.get(i).getDataArray().add(0);
                }
            }
        }
        //查看countDoDataList的长度是否和type集合长度相同，如果不同 找出不同并补全数据 返回结果赋值 不管有没有数据 之前一定会被附上一次type
        if (countDoDataList.size()!=types.size()){
            for (int i = 0; i < types.size(); i++) {
                if(types.get(i).equals(temptype)){ //和临时变量type名称相同的跳出本次循环
                    continue;
                }else {//不同的需要构造新的type
                    countDoData = new CountDoData();
                    //日期变量和 type变量 都需要改变
                    dataArray = new ArrayList<>();
                    //循环赋值0
                    for (int j = 0; j < dates.size(); j++) {
                        dataArray.add(0);
                    }
                    countDoData.setType(types.get(i));
                    countDoData.setDataArray(dataArray);
                    countDoDataList.add(countDoData);
                }
            }
        }
        Map<String,Object> resMap=new HashMap<>();
        for (CountDoData doData : countDoDataList) {
            resMap.put(doData.getType(),doData.getDataArray());
        }
        countResult.setyAjax(resMap);
        countResult.setxAjax(dates);
        //  countResult.setType(types);
        return countResult;
    }

    //分页查询数据
    public List<MessageEntity> findAllByLim(String page,String size){
        int p = Integer.parseInt(page);
        int s = Integer.parseInt(size);
        p = (p-1)*s;
        return messageRepository.findAllByLim(p, s);
    }

    //得到数据总数
    public Integer getCount(){
       return messageRepository.getCount();
    }

}
